﻿using Autofac;
using DbCore.Template;
using Sayook.Framework.AutoLibrary;
using Sayook.Framework.DbCore.DbContext;
using Sayook.Framework.DbCore.SqlModel;
using Sayook.Framework.Tools;
using System;
using System.Collections.Generic;
using System.Data;
using System.Threading.Tasks;

namespace DbCore
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            var autofacManager = new AutofacManager();
            var builder = new ContainerBuilder();
            builder.RegisterModule(new DbContextAutofacModule());
            autofacManager.SetContainer(builder.Build());
            var flag = "y";
            while (flag.Equals("y"))
            {
                Insert(999);

                Console.WriteLine("是否还要继续执行：y/n ？");
                flag = Console.ReadLine();
            }

            Console.WriteLine("Hello World!");
            Console.ReadLine();
        }

        public static void Query1()
        {
            using var Scope = AutofacManager.AutofacContainer.BeginLifetimeScope();
            var ids = new List<string> { "CIB", "CDB" };
            var dbContext = Scope.Resolve<CommonDbContext<BankInfo>>();
            var result = dbContext
                            .Where(x => SqlWhere.Set(x.BankCode, SqlOperator.NotIn, ids))
                            .And(x => SqlWhere.Set(x.BankName, SqlOperator.Like, "a"))
                            .ToList();
            Console.WriteLine($"context:{dbContext.GetHashCode()};result:{JsonHelper.ToJson(result)}");
        }

        public static void Query2()
        {
            var code = "CD";
            var uId = new int?[] { 4, 5, 7, 8, 9, 12, 14, 54, 24, 48, 30, 23 };
            using var Scope = AutofacManager.AutofacContainer.BeginLifetimeScope();
            var contest = Scope.Resolve<CommonDbContext<BankInfo>>();
            var result = contest.Select(x => new { x.Id, x.BankName, x.BankCode, x.CreatedByUser })
                            .Where(x => SqlWhere.Set(x.Id, SqlOperator.Between, 3, 30))
                            .And(x => SqlWhere.Set(x.BankName, SqlOperator.Equal))
                            .And(x => SqlWhere.Set(x.BankCode, SqlOperator.RightLike, code))
                            .And(x => SqlWhere.Set(x.CreatedByUser, SqlOperator.In, uId))
                            .SetParameter(new { BankName = "国家开发银行" })
                            .OrderBy(x => x.Id)
                            .ToList();
            Console.WriteLine($"context:{contest.GetHashCode()};result:{JsonHelper.ToJson(result)}");
        }

        public static void ParallelTest()
        {
            Parallel.For(112, 411, new ParallelOptions { MaxDegreeOfParallelism = 100 }, i =>
            {
                Insert(i);
            });
        }

        /// <summary>
        /// 新增
        /// </summary>
        public static void Insert(int id)
        {
            var info = new DatabaseInfo { Code = "SqlServer", DbName = "SqlServer", Description = "微软的Sqlserver数据库", ConnectionTemplate = "Data Source={服务器};Initial Catalog={数据库};Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False", CreateDate = DateTime.Now, LastModifyDate = DateTime.Now };
            using var Scope = AutofacManager.AutofacContainer.BeginLifetimeScope();
            var dbContext = Scope.Resolve<CommonDbContext<DatabaseInfo>>();
            var result = dbContext.Insert(info).SaveAndReturnId<int>();
            Console.WriteLine($"Insert_result:{result}");
        }

        /// <summary>
        /// UPDATE
        /// </summary>
        public static void Update()
        {
            using var Scope = AutofacManager.AutofacContainer.BeginLifetimeScope();
            var dbContext = Scope.Resolve<CommonDbContext<BankInfo>>();
            var result = dbContext.Update(x => x.BankName)
                .Where(x => SqlWhere.Set(x.Id, SqlOperator.Great))
                .And(x => SqlWhere.Set(x.Disable, SqlOperator.Equal))
                .SetParameter(new BankInfo { Id = 11, BankName = "国家开发银行", Disable = 1 })
                .Save();

            Console.WriteLine($"Update_result:{result}");
        }

        /// <summary>
        /// DELETE
        /// </summary>
        public static void DELETE()
        {
            using var Scope = AutofacManager.AutofacContainer.BeginLifetimeScope();
            var dbContext = Scope.Resolve<CommonDbContext<BankInfo>>();
            var result = dbContext.Delete()
                .Where(x => SqlWhere.Set(x.Id, SqlOperator.Equal))
                .SetParameter(new { Id = 410 })
                .Save();

            Console.WriteLine($"DELETE_result:{result}");
        }

        /// <summary>
        /// 执行事务
        /// </summary>
        public static void ExeTransaction()
        {
            using var Scope = AutofacManager.AutofacContainer.BeginLifetimeScope();
            var power = new PowerInfo { Id = 998, Description = "998", Remark = $"最后修改时间：{ DateTime.Now}", LastModifiedOn = DateTime.Now };
            var info1 = new BankInfo { Id = 8, BankCode = "CIB", Remark = "存一百！", BankName = "兴业银行", CreateOn = DateTime.Now, LastModifiedOn = DateTime.Now };
            void updatePower(IDbConnection dbConn, IDbTransaction transaction)
            {
                var dbContext = Scope.Resolve<CommonDbContext<PowerInfo>>();
                dbContext.Update(x => new { x.Name, x.Remark, x.LastModifiedOn })
                    .Where(x => SqlWhere.Set(x.Id, SqlOperator.Equal))
                    .SetParameter(power)
                    .TranSave(dbConn, transaction);
            }
            void insertBank(IDbConnection dbConn, IDbTransaction transaction)
            {
                var dbContext = Scope.Resolve<CommonDbContext<BankInfo>>();
                dbContext.Insert(info1)
                    .TranSave(dbConn, transaction);
            }
            var tranDbContext = Scope.Resolve<TranDbContext>();
            var result = tranDbContext
                .AddTransaction(updatePower)
                .AddTransaction(insertBank)
                .ExeTran();
        }
    }
}